
<template>
  <view class="activity-list">
    <up-navbar title="活动列表">
      <template #left>
        <view></view>
      </template>
    </up-navbar>
    <view class="fixed-header">
      <!-- 搜索框 -->
      <view class="search-box">
        <input v-model="searchKeyword" placeholder="输入活动名称搜索" />
      </view>


      <view class="filter-tabs">
        <text :class="{ active: filterType === 'all' }" @tap="setFilter('all')">全部 {{ totalAll }}</text>
        <text :class="{ active: filterType === 'joined' }" @tap="setFilter('joined')">已报名 {{ totalJoined }}</text>
        <text :class="{ active: filterType === 'not-expired' }" @tap="setFilter('not-expired')">未过期 {{ totalNotExpired }}</text>
        <text :class="{ active: filterType === 'not-joined' }" @tap="setFilter('not-joined')">未报名 {{ totalNotJoined }}</text>
      </view>
    </view>

    <view style="height: 44px;"></view>

    <view class="activity-list">
      <view v-for="(item, index) in filteredList" :key="index" class="activity-card">

      <image :src="item.poster" mode="aspectFill" class="activity-img"></image>
        <view class="activity-info">
          <view class="activity-title">{{ item.title }}</view>

          <!-- 时间区域 -->
          <view class="activity-time-row">
            <view class="time-badge">
              <up-icon name="clock" size="18" color="#ff9800" />
              <text class="time-text">{{ item.startTime }} 至 {{ item.endTime }}</text>
            </view>
            <view class="activity-desc">{{ item.description }}</view>
          </view>

<!--          &lt;!&ndash; 活动报名人数 &ndash;&gt;-->
<!--          <view class="enrollment-info">-->
<!--&lt;!&ndash;            <text class="enrolled-count">{{ item.joinedCount || 0 }}</text>&ndash;&gt;-->
<!--            <text class="slash"> 活动限制人数： </text>-->
<!--            <text class="max-count">{{ item.maxParticipants === 0 ? '无上限' : item.maxParticipants }}</text>-->
<!--          </view>-->

          <!-- 底部按钮区域 -->
          <view class="activity-footer">
            <view style="flex: 1;">
              <view
                  v-if="!isExpired(item.endTime)"
                  class="btn-primary"
                  :class="{ disabled: item.joined }"
                  @tap="!item.joined ? joinActivity(item) : null"
              >
                {{ item.joined ? '已报名' : '参加' }}
              </view>
              <view v-if="!isExpired(item.endTime)" class="btn-primary"
                    :class="{ disabled: item.checkedIn }"
                    @tap="handleJoinOrCheckIn(item)">
                <text v-if="item.canceled">已取消</text>
                <text v-else-if="item.checkedIn">已签到</text>
                <text v-else-if="item.joined">打卡</text>
                <text v-else>打卡</text>
              </view>

            </view>
            <view class="point-badge">+{{ item.point }} 积分</view>
          </view>
        </view>
      </view>
    </view>

    <!-- 加载提示 -->
    <view class="load-more" v-if="loading">加载中...</view>
    <view class="load-more" v-else-if="!hasMore && activityList.length">没有更多了</view>
  </view>
</template>


<script setup>



	import {
			ref,
			onMounted,
      computed
		} from 'vue'
		import {
			onReachBottom
		} from '@dcloudio/uni-app'
	
		import {
			getActivityPage,
      activityJoin,
      activityCheckIn
		} from '../../http/activity'
  import {getStudentActivities} from "../../http/student";
	
		const activityList = ref([])
		const defaultPoster = '/static/p1.jpg'
		const pageNum = ref(1)
		const pageSize = 100
		const hasMore = ref(true)
		const loading = ref(false)

  const searchKeyword = ref('')
  const filterType = ref('all')

  const totalActivities = ref(0)

  // 计算总数量
  const totalAll = computed(() => activityList.value.length)
  const totalJoined = computed(() => activityList.value.filter(item => item.joined).length)
  const totalNotExpired = computed(() => activityList.value.filter(item => !isExpired(item.endTime)).length)
  const totalNotJoined = computed(() => activityList.value.filter(item => !item.joined).length) // 新增

  // 过滤后的列表
  const filteredList = computed(() => {
    let list = [...(activityList.value || [])]

    // 搜索过滤
    if (searchKeyword.value.trim()) {
      const keyword = searchKeyword.value.toLowerCase()
      list = list.filter(item => item.title.toLowerCase().includes(keyword))
    }


    // 筛选过滤
    if (filterType.value === 'joined') {
      list = list.filter(item => item.joined)
    } else if (filterType.value === 'not-expired') {
      list = list.filter(item => !isExpired(item.endTime))
    }else if (filterType.value === 'not-joined') {
      list = list.filter(item => !item.joined) // 新增：未报名
    }

    return list
  })

  function setFilter(type) {
    filterType.value = type
  }


  const handleJoinOrCheckIn = (item) => {
    if (item.checkedIn) return // 已签到不可操作

    if (!item.joined) {
      joinActivity(item)
    } else {
      cardActivity(item)
    }
  }
	
		const fetchActivityList = async () => {
			if (loading.value || !hasMore.value) return
			loading.value = true
	
			const data = await getActivityPage(pageNum.value, pageSize)

      // 获取当前学生的报名记录
      const historyList = await getStudentActivities(studentId)
      const joinedIds = new Set(historyList.map(h => h.activityId))

      const joinedMap = {}
      historyList.forEach(h => {
        joinedMap[h.activityId] = h
      })

      // 合并数据：添加 joined 和 checkedIn 状态
      const list = data.records.map(item => {
        const history = joinedMap[item.id] || {}

        return {
          ...item,
          joined: history.status === 1 || history.status === 2, // 已报名或已签到
          checkedIn: history.status === 2,
          canceled: history.status === 3}
      })

      // 更新总活动数量
      totalActivities.value = activityList.value.length

      activityList.value.push(...list)
      pageNum.value++
      // activityList.value.push(...data.records)
			if (data.total <= activityList.value.length) hasMore.value = false
			loading.value = false
		}
	
		const isExpired = (endTime) => {
			if (!endTime) return false
			return new Date(endTime.replace(/-/g, '/')).getTime() < Date.now()
		}

  // 获取学生ID和姓名（从本地缓存中读取）
  const studentId = uni.getStorageSync("studentId")
  const studentName = uni.getStorageSync("studentName")

  // 参加活动
  const joinActivity = (item) => {
    if (item.joined) return;
    activityJoin(
        studentId,
        item.id,
        studentName,
        item.activityName || item.title,
        item.point
    ).then(data => {
      uni.showToast({ title: `报名成功`, icon: 'success' })

      // 本地更新状态，避免重新请求数据
      item.joined = true;
    }).catch(err => {
      uni.showToast({ title: `报名失败`, icon: 'none' })
      console.error('报名失败:', err)
    })
  }

  // 打卡
  const cardActivity = (item) => {
    if (item.checkedIn) return; // 防止重复签到

    activityCheckIn(studentId, item.id).then(data => {
      uni.showToast({ title: `打卡成功`, icon: 'success' })
      // 本地更新签到状态
      item.checkedIn = true;
      // 可选：更新该活动的打卡状态
    }).catch(err => {
      uni.showToast({ title: `打卡失败`, icon: 'none' })
      console.error('打卡失败:', err)
    })
  }


  onMounted(() => { // 页面显示的时候
			fetchActivityList()
		})
	
		onReachBottom(() => { // 页面滚到最底部的时候
			if (hasMore.value && !loading.value) {
				fetchActivityList()
			}
		})
</script>

<style>
.fixed-header {
  position: sticky;
  top: 44px; /* up-navbar 高度 */
  z-index: 999;
  background-color: #fff;
}
.search-box {
  position: sticky;
  top: 44px;
  z-index: 99;
  background-color: #fff;
  padding: 20rpx;
  box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.06);
}

.search-box input {
  padding: 16rpx 30rpx;
  border-radius: 32rpx;
  background: #f0f0f0;
  font-size: 26rpx;
}

.filter-tabs {
  display: flex;
  justify-content: space-around;
  padding: 16rpx 0;
  background-color: #fff;
  border-bottom: 1rpx solid #eee;
}

.filter-tabs text {
  padding: 8rpx 24rpx;
  font-size: 26rpx;
  color: #666;
}

.filter-tabs .active {
  color: #1890ff;
  font-weight: bold;
  border-bottom: 2rpx solid #1890ff;
}

/* 已签到按钮 */
.btn-primary.btn-signed {
  background-color: #4caf50;
  color: #fff;
  pointer-events: none;
}


.activity-list {
  padding: 24rpx;
  background: #f7f9fa;
}

.activity-card {
  background: #fff;
  border-radius: 20rpx;
  box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.06);
  margin-bottom: 32rpx;
  overflow: hidden;
  position: relative;
}

.activity-img {
  width: 100%;
  height: 140px;
  object-fit: cover;
  background: #f2f2f2;
}

.expired-badge {
  position: absolute;
  top: 16rpx;
  right: 16rpx;
  background: linear-gradient(90deg, #ff6161 0%, #ff3c3c 100%);
  color: #fff;
  font-size: 22rpx;
  font-weight: 600;
  border-radius: 24rpx;
  padding: 6rpx 24rpx;
  z-index: 2;
}

.activity-info {
  padding: 14px 12px 10px 12px;
  display: flex;
  flex-direction: column;
}

.activity-title {
  font-size: 17px;
  font-weight: bold;
  color: #222;
  margin-bottom: 8px;
}

.activity-time-row {
  margin-bottom: 12rpx;
}

.time-badge {
  display: inline-flex;
  align-items: center;
  background-color: #fff7e6;
  color: #ff9800;
  border-radius: 20rpx;
  padding: 6rpx 20rpx;
  font-size: 22rpx;
  font-weight: 500;
}

.time-text {
  margin-left: 8rpx;
  color: #ff9800;
  font-size: 22rpx;
}

.activity-desc {
  font-size: 26rpx;
  color: #666;
  margin-bottom: 18rpx;
  line-height: 36rpx;
  min-height: 72rpx;
}

.activity-footer {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  align-items: center;
}

/* 主要操作按钮样式 */
.btn-primary {
  background: linear-gradient(90deg, #3ec6fd 0%, #1890ff 100%);
  color: #fff;
  font-size: 26rpx;
  border-radius: 32rpx;
  padding: 10rpx 40rpx;
  font-weight: 600;
  margin-right: 16rpx;
  box-shadow: 0 2rpx 8rpx rgba(24, 144, 255, 0.12);
  transition: background 0.2s;
  display: inline-block;
  text-align: center;
  cursor: pointer;
  line-height: 1.5;
}

.btn-primary:active {
  background: linear-gradient(90deg, #1890ff 0%, #3ec6fd 100%);
}

/* 禁用状态按钮 */
.btn-primary.disabled {
  background-color: #ccc;
  color: #666;
  pointer-events: none;
}

/* 积分徽章 */
.point-badge {
  background: linear-gradient(90deg, #ff9a44 0%, #ff6a00 100%);
  color: #fff;
  font-size: 24rpx;
  font-weight: 600;
  border-radius: 24rpx;
  padding: 8rpx 24rpx;
  box-shadow: 0 2rpx 8rpx rgba(255, 106, 0, 0.12);
  letter-spacing: 1rpx;
  display: inline-block;
}

/* 加载更多提示 */
.load-more {
  text-align: center;
  color: #bbb;
  font-size: 26rpx;
  margin: 40rpx 0 20rpx 0;
}

.enrollment-info {
  margin-top: 12rpx;
  font-size: 24rpx;
  color: #666;
}

.enrolled-count {
  color: #1890ff;
  font-weight: bold;
}

.slash {
  margin: 0 4rpx;
}

.max-count {
  color: #999;
}

</style>





